import type {AxiosError, AxiosInstance, AxiosRequestConfig, AxiosResponse, InternalAxiosRequestConfig} from 'axios'
import axios from 'axios'
import {ElMessage} from 'element-plus'
import {LOCAL_STORE, STORE_KEY_CURRENT_USER_ID} from './StorageUtil';
import {SillyResult} from "@/core/entity/SillyResult";

const SILLY_ADMIN_CURRENT_USER_ID_HEADER_NAME = "SILLY_ADMIN_CURRENT_USER_ID";

const service: AxiosInstance = axios.create({
    baseURL: import.meta.env.VITE_APP_BASE_API,
    timeout: 60000
});


/* 请求拦截器 */
service.interceptors.request.use((config: InternalAxiosRequestConfig) => {
    const userId = LOCAL_STORE.getItem(STORE_KEY_CURRENT_USER_ID);
    if (userId) {
        config.headers[SILLY_ADMIN_CURRENT_USER_ID_HEADER_NAME] = userId;
    } else {
        delete config.headers[SILLY_ADMIN_CURRENT_USER_ID_HEADER_NAME];
    }
    return config;
}, (error: AxiosError) => {
    ElMessage({
        showClose: true,
        message: error.message,
        type: 'error',
    });
    return Promise.reject(error)
});


/* 响应拦截器 */
service.interceptors.response.use((response: AxiosResponse) => {
    const {code, message, data} = response.data

    // 根据自定义错误码判断请求是否成功
    if (code === 0) {
        return data;
    } else {
        ElMessage({
            showClose: true,
            message: message,
            type: 'warning',
        });
        return Promise.reject(new Error(message))
    }
}, (error: AxiosError) => {
    // 处理 HTTP 网络错误
    let message = ''
    // HTTP 状态码
    const status = error.response?.status
    switch (status) {
        case 401:
            message = 'token 失效，请重新登录'
            break;
        case 403:
            message = '拒绝访问'
            break;
        case 404:
            message = '请求地址错误'
            break;
        case 500:
            message = '服务器故障'
            break;
        default:
            message = '网络连接故障'
    }
    ElMessage({
        showClose: true,
        message: message,
        type: 'error',
    });
    return Promise.reject(error)
});


/* 导出封装的请求方法 */
export const http = {
    get<T = SillyResult>(url: string, config?: AxiosRequestConfig): Promise<T> {
        return service.get(url, config)
    },

    post<T = SillyResult>(url: string, data?: object, config?: AxiosRequestConfig): Promise<T> {
        return service.post(url, data, config)
    },

    put<T = SillyResult>(url: string, data?: object, config?: AxiosRequestConfig): Promise<T> {
        return service.put(url, data, config)
    },

    delete<T = SillyResult>(url: string, config?: AxiosRequestConfig): Promise<T> {
        return service.delete(url, config)
    }
};
